package errcode

// 业务错误码定义
const (
	// 通用错误码 1000-1999
	Success            = 0
	BadRequest         = 1000
	Unauthorized       = 1001
	Forbidden          = 1003
	NotFound           = 1004
	InternalError      = 1500
	ServiceUnavailable = 1503

	// 认证相关错误码 2000-2099
	InvalidCredentials   = 2000 // 用户名或密码错误
	UserExists           = 2001 // 用户已存在
	EmailExists          = 2002 // 邮箱已被注册
	PhoneExists          = 2003 // 手机号已被注册
	UserNotFound         = 2004 // 用户不存在
	UserDisabled         = 2005 // 账号已被禁用
	InvalidToken         = 2006 // Token无效
	TokenExpired         = 2007 // Token已过期
	TokenBlacklisted     = 2008 // Token已失效
	InvalidRefreshToken  = 2009 // RefreshToken无效
	OldPasswordIncorrect = 2010 // 原密码错误

	// 参数验证错误码 3000-3099
	InvalidUsername = 3000 // 用户名格式错误
	InvalidPassword = 3001 // 密码格式错误
	InvalidEmail    = 3002 // 邮箱格式错误
	InvalidPhone    = 3003 // 手机号格式错误
	PasswordTooWeak = 3004 // 密码强度不足

	// 限流错误码 4000-4099
	TooManyRequests = 4000 // 请求过于频繁

	// 权限错误码 5000-5099
	PermissionDenied   = 5000 // 权限不足
	RoleNotFound       = 5001 // 角色不存在
	RoleDisabled       = 5002 // 角色已被禁用
	PermissionNotFound = 5003 // 权限不存在
	PermissionExists   = 5004 // 权限已存在

	// 业务逻辑错误码 6000-6999
	MemberNotFound = 6000 // 会员不存在
	CourseNotFound = 6001 // 课程不存在
	CoachNotFound  = 6002 // 教练不存在
	PlanNotFound   = 6003 // 健身计划不存在

	// 课程预约错误码 6100-6199
	BookingNotFound      = 6100 // 预约不存在
	BookingExists        = 6101 // 已预约该课程
	CourseFullyBooked    = 6102 // 课程已满
	CourseNotAvailable   = 6103 // 课程不可预约
	BookingTimeConflict  = 6104 // 预约时间冲突
	BookingCancelled     = 6105 // 预约已取消
	CannotCancelBooking  = 6106 // 无法取消预约
	CannotCheckIn        = 6107 // 无法签到
	CheckInTimeNotReady  = 6108 // 签到时间未到
	CourseAlreadyStarted = 6109 // 课程已开始
	CourseNotStarted     = 6110 // 课程未开始
	AlreadyCheckedIn     = 6111 // 已签到
)

// 错误信息映射
var ErrorMessages = map[int]string{
	Success:            "成功",
	BadRequest:         "请求参数错误",
	Unauthorized:       "未授权",
	Forbidden:          "禁止访问",
	NotFound:           "资源不存在",
	InternalError:      "服务器内部错误",
	ServiceUnavailable: "服务暂不可用",

	InvalidCredentials:   "用户名或密码错误",
	UserExists:           "用户名已存在",
	EmailExists:          "邮箱已被注册",
	PhoneExists:          "手机号已被注册",
	UserNotFound:         "用户不存在",
	UserDisabled:         "账号已被禁用",
	InvalidToken:         "Token无效",
	TokenExpired:         "Token已过期",
	TokenBlacklisted:     "Token已失效",
	InvalidRefreshToken:  "RefreshToken无效或已过期",
	OldPasswordIncorrect: "原密码错误",

	InvalidUsername: "用户名格式错误",
	InvalidPassword: "密码格式错误",
	InvalidEmail:    "邮箱格式错误",
	InvalidPhone:    "手机号格式错误",
	PasswordTooWeak: "密码强度不足",

	TooManyRequests: "请求过于频繁，请稍后再试",

	PermissionDenied:   "权限不足",
	RoleNotFound:       "角色不存在",
	RoleDisabled:       "角色已被禁用",
	PermissionNotFound: "权限不存在",
	PermissionExists:   "权限代码已存在",

	MemberNotFound: "会员不存在",
	CourseNotFound: "课程不存在",
	CoachNotFound:  "教练不存在",
	PlanNotFound:   "健身计划不存在",

	BookingNotFound:      "预约不存在",
	BookingExists:        "您已预约该课程，请勿重复预约",
	CourseFullyBooked:    "课程已满，无法预约",
	CourseNotAvailable:   "课程不可预约",
	BookingTimeConflict:  "该时间段已有其他课程预约",
	BookingCancelled:     "预约已取消",
	CannotCancelBooking:  "课程开始前2小时不允许取消",
	CannotCheckIn:        "无法签到",
	CheckInTimeNotReady:  "签到时间未到，课程开始前30分钟开放签到",
	CourseAlreadyStarted: "课程已开始或已结束",
	CourseNotStarted:     "课程未开始",
	AlreadyCheckedIn:     "已签到，请勿重复签到",
}

// GetMessage 获取错误信息
func GetMessage(code int) string {
	if msg, ok := ErrorMessages[code]; ok {
		return msg
	}
	return "未知错误"
}

// BusinessError 业务错误
type BusinessError struct {
	Code    int
	Message string
}

func (e *BusinessError) Error() string {
	return e.Message
}

// NewError 创建业务错误
func NewError(code int, message ...string) *BusinessError {
	msg := GetMessage(code)
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}
	return &BusinessError{
		Code:    code,
		Message: msg,
	}
}
